package net.sangpil.applications.project.architecture
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	
	import net.sangpil.applications.project.architecture.Building3DViewerWithFlv.UVmapWithAdditionalBitmapData;
	import net.sangpil.applications.viewer.CameraPositionViewer;
	import net.sangpil.applications.viewer.SkinVideo;
	import net.sangpil.applications.viewer.Viewer3D;
	import net.sangpil.applications.viewer.ViewerMap;
	import net.sangpil.applications.viewer.event.CameraPositionViewerEvent;
	import net.sangpil.applications.viewer.event.SkinVideoEvent;
	import net.sangpil.applications.viewer.event.Viewer3dEvent;
	import net.sangpil.applications.viewer.event.ViewerMapEvent;
	import net.sangpil.classes.events.SimpleLoaderEvent;
	import net.sangpil.classes.interactions.MouseDrag;
	import net.sangpil.classes.net.SimpleLoader;
	import net.sangpil.classes.utils.math.Divide;
	
	import org.papervision3d.core.proto.MaterialObject3D;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.parsers.Collada;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.objects.primitives.Plane;

	public class Building3DViewerSeoulSquare extends Sprite
	{
		//1200 700
		private var windowWidth:Number;
		private var windowHeight:Number;
		
		private var background:Bitmap;
		private var nb_background:Bitmap;
		private var _navi_Panel:Sprite;
		
		private var vidSizePerW:Number = 0.3;
		private var viewer3DPerH:Number = 1;
		private var shapeSpace:Number = 5;
		
		private var building_bottom_bm:Bitmap;
		private var imgLoader:SimpleLoader;
		private var	labelLoader:SimpleLoader;
		private var labelClip:Bitmap;
		
		private var vid:SkinVideo;
		private var viewer:Viewer3D;
		private var dividNumber:uint = 4;
		private var _bObjectY:Number = 0;
		private var camPosViewer:CameraPositionViewer;
		private var camPosLimiteDis:uint = 2000;
		private var mapViewer:ViewerMap;
		private var ledController:LedSettingClip; 
		private var liveUvMap:UVmapWithAdditionalBitmapData;
		
		private var cubeHeight:Number = 752;
		private var cubeWidth:Number = 357;
		private var cubeDepth:Number = 357;
		private var sbLED_w:Number = 11.2;
		private var sbLED_h_3:Number = 30;
		private var visDis:uint = 4;
		private var visDisLimit:uint = 10;
		private var currentLedSize:uint = 4;
		private var winColSha:uint = 0x333333;
		private var winCol:uint = 0x666666;
		
		private var setPos20Arr:Array = [];
		private var setPos30Arr:Array = [];
		
		private var capPos20Arr:Array = [];
		private var capPos30Arr:Array = [];
		
		private var capturePadArr:Array;
		private var captureClipArr:Array;
		
		private var tempArr:Array;
		
		private var map:Bitmap;
		
		public function Building3DViewerSeoulSquare(windowWidth:Number, windowHeight:Number)
		{
			super();
			this.windowWidth = windowWidth;
			this.windowHeight = windowHeight;
			this.addEventListener(Event.ADDED_TO_STAGE, onStage);
		}
		
		private function onStage(e:Event):void
		{
			this.init();	
		}
		
		private function init():void
		{
			this.curVidSizeW = this.windowWidth*this.vidSizePerW;
			this.captureClipArr = new Array();
			
			for(var i:uint = 0; i < this.dividNumber; i++)
			{
				this.captureClipArr[i] = new captureClip();
			}
			
			var bg_bd:BitmapData = new BitmapData(this.windowWidth, this.windowHeight+50, false, 0x000000);
			this.background = new Bitmap(bg_bd);
			this.addChild(this.background);			
			
			this._navi_Panel = new Sprite();
			this.addChild(this._navi_Panel);
			
			var nb_bg_bd:BitmapData = new BitmapData(this.curVidSizeW+this.shapeSpace*2, 1, false, 0x000000);
			this.nb_background = new Bitmap(nb_bg_bd);
			this._navi_Panel.addChild(this.nb_background);
			
			
			this.setLayout();
			this.addEvent();
			
			var mTimer:Timer = new Timer(500, 1);
			mTimer.addEventListener("timer", timerHandler);
			mTimer.start();
		}
		
		private function timerHandler(e:TimerEvent):void
		{
			this.viewer.camera.y += -50;
			this.viewer.singleRender();
		}
		
		private var curVidSizeW:Number;
		private function setLayout():void
		{			
			this.vid = new SkinVideo(this.curVidSizeW);
			this._navi_Panel.addChild(this.vid);
			
			this.camPosViewer = new CameraPositionViewer(this.curVidSizeW);
			this._navi_Panel.addChild(this.camPosViewer);
			
			this.mapViewer = new ViewerMap(this.curVidSizeW, 14.25, "./imageAssets/MapData.png");
			this._navi_Panel.addChild(this.mapViewer);
			
			this.ledController = new LedSettingClip();
			this._navi_Panel.addChild(this.ledController);
			this.ledController.btn_browse.buttonMode = true;
			this.ledController.btn_browse.width = this.curVidSizeW;
			this.ledController.txt_url.text = "LED Space & Diffuse Limite";
			this.ledController.txt_url.width = this.curVidSizeW;
			var w:Number = this.sbLED_w*100;
			var h:Number = this.sbLED_h_3*100;
			var s:Number = this.visDisLimit*100;
			this.ledController.txt_space_w.text = w.toString();
			this.ledController.txt_space_h.text = h.toString();
			this.ledController.txt_size_w.text = s.toString();
			this.ledController.txt_col_light.text = this.winCol.toString(16);
			//this.ledController.txt_col_shadow.text = this.winColSha.toString(16);
			this.ledController.bg_second.width = this.curVidSizeW;
			this.ledController.bg_secon2.width = this.curVidSizeW;
			
			this.viewer = new Viewer3D(this.windowWidth - this.shapeSpace*3 - this.curVidSizeW, (this.windowHeight-this.shapeSpace*2)*this.viewer3DPerH);
			this.addChild(this.viewer);
			
			this.layoutRearrange();
			
			this.gotCapturePosition(800, 600);			
			
			this.imgLoader = new SimpleLoader();
			this.labelLoader = new SimpleLoader();
		}
		
		private function layoutRearrange():void
		{			
			this._navi_Panel.y = 0;
			
			this.vid.x = this.shapeSpace;
			this.vid.y = this._navi_Panel.y + this.shapeSpace;
			
			this.camPosViewer.x = this.shapeSpace; 
			this.camPosViewer.y = this._navi_Panel.y + this.vid.height + shapeSpace*2;
			
			this.ledController.x = shapeSpace;
			this.ledController.y = this._navi_Panel.y + this.vid.height + shapeSpace*3 + this.camPosViewer.height;
			
			this.mapViewer.x = shapeSpace;
			this.mapViewer.y = this._navi_Panel.y + this.vid.height + shapeSpace*4 + this.camPosViewer.height + this.ledController.height;
			
			this.nb_background.height = this._navi_Panel.y + this.vid.height + shapeSpace*5 + this.camPosViewer.height + this.mapViewer.height + this.ledController.height; 
			
			this.viewer.x = this.shapeSpace*2 + this.curVidSizeW;
			this.viewer.y = this.shapeSpace;
		}
		
		private function addEvent():void
		{
			this._navi_Panel.addEventListener(MouseEvent.MOUSE_WHEEL, naviWheel);
			
			this.vid.addEventListener(SkinVideoEvent.VIDEO_LOADED, vidLoaded);
			this.vid.addEventListener(SkinVideoEvent.VIDEO_REPLAY, vidReLoaded);
			
			this.camPosViewer.addEventListener(CameraPositionViewerEvent.CAMERA_MOVE, mapCamMove);
			this.mapViewer.addEventListener(ViewerMapEvent.MAP_LOADED, mapLoaded);
			this.ledController.txt_size_w.addEventListener(KeyboardEvent.KEY_DOWN, ledArrChangeStart);
			this.ledController.txt_space_w.addEventListener(KeyboardEvent.KEY_DOWN, ledArrChangeStart);
			this.ledController.txt_space_h.addEventListener(KeyboardEvent.KEY_DOWN, ledArrChangeStart);
			this.ledController.txt_col_light.addEventListener(KeyboardEvent.KEY_DOWN, ledArrChangeStart);
			//this.ledController.txt_col_shadow.addEventListener(KeyboardEvent.KEY_DOWN, ledArrChangeStart);
			
			this.imgLoader.addEventListener(SimpleLoaderEvent.COMPLETED, imageLoaded);
			this.imgLoader.load("modelling_d.png");
			
			this.viewer.addEventListener(Viewer3dEvent.CAMERA_POS_CHANGE, camPosChange);
			this.viewer.addEventListener(Viewer3dEvent.OBJECT_POS_CHANGE, objPosChange);
		}

		private function mapCamMove(e:CameraPositionViewerEvent):void
		{
			var point:Point = new Point(e.position.x, e.position.y);
			this.viewer.updateCamera(point);
		}
		
		private var currentDistance:Number;
		private function camPosChange(e:Viewer3dEvent):void
		{
			this.currentDistance = Math.sqrt(e.p3Dx*e.p3Dx + e.p3Dz*e.p3Dz);
			this.camPosViewer.upDateCameraPos(e.p3Dx, e.p3Dy, e.p3Dz, e.r3Dx, e.r3Dy, e.r3Dz);
			this.camPosViewer.updateCameraDistance(Math.round(this.currentDistance)/10);
			this.ledSizeChanger();
		}
		
		private function ledSizeChanger():void
		{
			//trace("ledSizeChanger");
			var rat:Number = this.camPosLimiteDis/this.visDisLimit;
			this.currentLedSize = Math.round(this.currentDistance/rat);
			 
			if(this.visDis != this.currentLedSize)
			{
				trace("ledSizeChanger_in");
				//trace(this.currentDistance, this.visDis, this.currentLedSize);
				this.visDis = this.currentLedSize;
				
				this.cubeSkinReset();
				this.drawWindow();
			}			
		}
		
		private function objPosChange(e:Viewer3dEvent):void
		{
			this.camPosViewer.upDateObjectPos(e.p3Dx, e.p3Dy, e.p3Dz, e.r3Dx, e.r3Dy, e.r3Dz);
		}
		
		private function ledArrChangeStart(e:KeyboardEvent):void
		{
			if(e.keyCode == 13)
			{
				var w:Number = Number(this.ledController.txt_space_w.text)/100;
				var h:Number = Number(this.ledController.txt_space_h.text)/100;
				var s:int = int(this.ledController.txt_size_w.text)/100;
				
				//trace();
				var strC:String = "0x"+this.ledController.txt_col_light.text;
				this.winCol = uint(strC);
				//trace("col ", strC);
				
				/* var strS:String = "0x"+this.ledController.txt_col_shadow.text;
				this.winColSha = uint(strS); */
				
				this.sbLED_h_3 = h;
				this.sbLED_w = w;
				this.visDisLimit = s;
				
				this.ledArrChangeMiddle();	
			}			
		}
		
		private function ledArrChangeMiddle():void
		{
			trace("ledArrChangeMiddle");
			this.removeEventListener(Event.ENTER_FRAME, this.onEnter);
			
			this.cubeSkinReset();
			
			this.gotCapturePosition(this.vid.vid.width, this.vid.vid.height);
			
			this.drawWindow(false);
			
			this.addEventListener(Event.ENTER_FRAME, this.onEnter);
		}
		
		private function cubeSkinReset(firstTry:Boolean = true):void
		{
			trace("cubeSkinReset");
			if(this.cube)
			{
				var tempArr:Array = ["front","back","right","left"];
				var rec:Rectangle = new Rectangle(0, 0, this.cubeWidth, this.cubeHeight);
				
				for(var i:uint = 0; i < tempArr.length; i++)
				{
					var temp:MaterialObject3D = this.cube.materials.getMaterialByName(tempArr[i]);
					temp.bitmap.fillRect(rec, 0x000000);
				}
			}
		}
		
		private var ledOnOffArr:Array;
		private var onoffcnt:uint;
		private function drawWindow(firstTry:Boolean = false):void
		{
			trace("drawWindow");
			this.onoffcnt = 0;
			if(this.cube)
			{
				if(firstTry)
				{
					this.ledOnOffArr = null;
					this.ledOnOffArr = new Array();
				}
				var tempArr:Array = ["front","back","right","left"];
				var rec:Rectangle = new Rectangle(0, 0, this.cubeWidth, this.cubeHeight);
				
				for(var i:uint = 0; i < tempArr.length; i++)
				{
					var temp:MaterialObject3D = this.cube.materials.getMaterialByName(tempArr[i]);
					var sArr:Array = this.setPos30Arr[i];
					for(var j:uint = 0; j< sArr.length; j++)
					{
						if(firstTry)
						{
							var tmNum:uint = 1;//Math.round(Math.random());
							this.ledOnOffArr.push(tmNum);
						}
						var spX:uint = sArr[j].x;
						var spY:uint = sArr[j].y;
						var spOnOff:uint = this.ledOnOffArr[this.onoffcnt];
						if(spOnOff == 1)
						{
							var tempCol:uint = this.winCol;
							var anoRect:Rectangle = new Rectangle(spX+1, spY+1, this.sbLED_w-1, this.sbLED_h_3-1);
						 	
							temp.bitmap.fillRect(anoRect, tempCol);
							
							/* var tempCol2:uint = this.winColsh;
							var anoRect2:Rectangle = new Rectangle(spX+3, spY+3, this.sbLED_w-3, this.sbLED_h_3-3);
							temp.bitmap.fillRect(anoRect2, tempCol2); */
						}
						this.onoffcnt+=1;
					}
				}
			}
		}
		
		
		
		private function naviWheel(e:MouseEvent):void
		{
			//trace(e.delta);
			if(this._navi_Panel.height < this.windowHeight)
			{
				if(this._navi_Panel.y >= 0)
				{
					this._navi_Panel.y += e.delta*2;
					if(this._navi_Panel.y < 0)
					{
						this._navi_Panel.y = 0;
					}else if(this._navi_Panel.y + this._navi_Panel.height >= this.windowHeight){
						this._navi_Panel.y = this.windowHeight - this._navi_Panel.height;
					}
				}
			}else{
				this._navi_Panel.y += e.delta*4;
				if(this._navi_Panel.y + this._navi_Panel.height < this.windowHeight)
				{
					this._navi_Panel.y = this.windowHeight - this._navi_Panel.height;
				}else{
					if(this._navi_Panel.y > 0)
					{
						this._navi_Panel.y = 0;
					}
				}
				
			}
		}
		
		/* events */
		
		/* when video loaded */
		private function vidLoaded(e:SkinVideoEvent):void
		{
			this.gotCapturePosition(this.vid.vid.width, this.vid.vid.height);
			trace(this.vid.vid.width, this.vid.vid.height);
			
			for(var i:uint = 0; i < captureClipArr.length; i++)
			{
				var cpc:captureClip = this.captureClipArr[i] as captureClip;
				var mi:MouseDrag = new MouseDrag(cpc);
				cpc.x = 102 * i;
				cpc.txt.text = i.toString();
				//this.vid.addChild(cpc);
			}
			
			this.onUVmapScale();
			this.layoutRearrange();			
		}
		
		private var mapPlane:Plane;
		private var mapMaterial:BitmapMaterial;
		private function mapLoaded(e:ViewerMapEvent):void
		{
			this.layoutRearrange();
			
			//trace(this.mapViewer.bitmapData.width, this.mapViewer.bitmapData.height);
			if(this.mapMaterial)
			{
				this.viewer.basicObject.removeChild(this.mapPlane);
				this.mapMaterial = null;
				
				this.mapPlane = null;
			}
			
			this.camPosViewer.addMap(this.mapViewer.bitmapData);
			this.mapMaterial = new BitmapMaterial(this.mapViewer.bitmapData, true);
			
			
			
			this.mapPlane = new Plane(this.mapMaterial ,this.mapViewer.bitmapData.width, this.mapViewer.bitmapData.height, 30, 30);
			this.mapPlane.scale *= 10;
			this.mapPlane.rotationX = 90;
			this.mapPlane.y = -537 + _bObjectY;
			this.viewer.basicObject.addChild(this.mapPlane); 
			this.viewer.singleRender();
		}
		
		private function vidReLoaded(e:SkinVideoEvent):void
		{
			this.gotCapturePosition(this.vid.vid.width, this.vid.vid.height);
			this.layoutRearrange();
		}
		
		private function imageLoaded(e:SimpleLoaderEvent):void
		{
			/* make cube */
			this.makeCube();
			
			/* add bottom building to scene.basicObject */
			this.building_bottom_bm = e.content as Bitmap;
			var mtl:MaterialsList = new MaterialsList();
			var bmt:BitmapMaterial = new BitmapMaterial(this.building_bottom_bm.bitmapData, true);
			mtl.addMaterial(bmt, "modelling_down_png");
			var building_bottom:Collada = new Collada("model_down.dae", mtl);
			building_bottom.scale *= 2.2;
			building_bottom.y += _bObjectY;
			this.viewer.basicObject.addChild(building_bottom);
		}
		
		private var count:uint = 0;
		private function gotCapturePosition(w:Number, h:Number):void
		{
			var wdnum:uint = this.dividNumber;
			
			var divideSpace:uint = Divide.IntType(w, wdnum);
			
			for(var i:uint = 0; i < wdnum; i++) //big 4 rectangles.
			{
				this.getSetAndCapPosition(	
											this.setPos30Arr,
											this.capPos30Arr, 
											i, 
											divideSpace,
											w,
											h,
											this.sbLED_w,
											this.sbLED_h_3
											);
											
				/* var cpc:captureClip = this.captureClipArr[i] as captureClip;
				var mi:MouseDrag = new MouseDrag(cpc);
				cpc.x = divideSpace * i;
				cpc.width = divideSpace;
				cpc.height = h;
				cpc.txt.text = i.toString();
				this.vid.addChild(cpc); */
			}
			
		}
		
		private function getSetAndCapPosition(
												arrCubeLed:Array, 
												arrVidLed:Array, 
												arrNum:uint, 
												divideSp:Number,
												w:Number,
												h:Number,
												cubeSpX:Number,
												cubeSpY:Number
												):void
		{
			var countX:Number = this.cubeWidth/cubeSpX;
			var countY:Number = this.cubeHeight/cubeSpY;
			
			var vidSpX:Number = divideSp/countX;
			var vidSpY:Number = h/countY;
			
			arrCubeLed[arrNum] = null;
			arrCubeLed[arrNum] = new Array();
			var arr_dot_cube:Array = arrCubeLed[arrNum];
			
			arrVidLed[arrNum] = null;
			arrVidLed[arrNum] = new Array();
			var arr_dot_vid:Array = arrVidLed[arrNum];
			
			for(var i:uint = 0; i < countX; i++)
			{
				for(var j:uint = 0; j < countY; j++)
				{
					var cubePoint:Point = new Point(Math.round(i*cubeSpX), Math.round(j*cubeSpY));
					arr_dot_cube.push(cubePoint);
					
					var vidPoint:Point = new Point(Math.round(i*vidSpX+divideSp*arrNum), Math.round(j*vidSpY));
					arr_dot_vid.push(vidPoint);
				}
			} 
			
		}
		
		private function makeCube():void
		{
			//add building up part to 3d viewer
			trace("collada loaded");
			
			var bt:BitmapData = new BitmapData(this.cubeWidth, this.cubeHeight, false, 0x222222);
			
			var mtl:MaterialsList = new MaterialsList();
			
			for(var i:uint = 0; i < 4; i++)
			{
				var btf:BitmapData = new BitmapData(this.cubeWidth, this.cubeHeight, false, 0x000000);
				
				this.moArr[i] = new BitmapMaterial(btf, true);
				var mo:BitmapMaterial = this.moArr[i];
				mo.smooth = true;
				
				switch (i)
				{
					case 0:
						mtl.addMaterial(mo, "back");
						break;
					case 1:
						mtl.addMaterial(mo, "left");
						break;
					case 2:
						mtl.addMaterial(mo, "front");
						break;
					case 3:
						mtl.addMaterial(mo, "right");
						break;			
				}
			}
			
			mtl.addMaterial(new BitmapMaterial(bt), "top");
			mtl.addMaterial(new BitmapMaterial(bt), "bottom");
			
			this.cube = new Cube(mtl, this.cubeWidth, this.cubeDepth, this.cubeHeight, 10, 1, 10);
			this.cube.y += 110 + _bObjectY;
			
			this.drawWindow(true);
						
			this.viewer.basicObject.addChild(cube);
		}
		
		/* 라이브 생겼을 때. */
		private var con:Sprite;
		private var moArr:Array = [];
		private var cube:Cube
		private function onUVmapScale():void
		{
			
			this.addEventListener(Event.ENTER_FRAME, onEnter);
			
			/* var bm:BitmapData = new BitmapData(vid.width, this.height-this.vid.height+10, false, 0x000000);
			this.map = new Bitmap(bm);
			this.map.x = this.shapeSpace;
			this.map.y = this.vid.height + this.shapeSpace*2;
			this.addChild(this.map); */
		}
		
		
		private function onEnter(e:Event):void
		{
 			var vidBMD:BitmapData = this.vid.bitmapData;
			
			for(var j:uint = 0; j < 4; j++)
			{
				var cArr:Array = this.capPos30Arr[j];
				var sArr:Array = this.setPos30Arr[j];
				
				var nm:String;
				switch (j)
				{
					case 0: //동영상 순서.
						nm = "left"; 
						break;
					case 3:
						nm = "front";
						break;
					case 2:
						nm = "right";
						break;
					case 1: 
						nm = "back";  
						break;			
				}
				
				var temp:MaterialObject3D = this.cube.materials.getMaterialByName(nm);
				
				for(var i:uint = 0; i< cArr.length; i++)
				{
					var cpX:uint =  cArr[i].x;
					var cpY:uint =  cArr[i].y;
					
					var spX:uint = sArr[i].x;
					var spY:uint = sArr[i].y;
					
					var col:uint = vidBMD.getPixel(cpX, cpY);
					var rect:Rectangle = new Rectangle(spX, spY, visDis, visDis);
					temp.bitmap.fillRect(rect, col);
					
					/* var tempCol:uint = 0xFF0000;
					var anoRect:Rectangle = new Rectangle(spX+2, spY+2, this.sbLED_w-2, this.sbLED_h_3-2);
					temp.bitmap.fillRect(anoRect, tempCol); */
				} 
				
				temp.updateBitmap();
			}
			
			this.viewer.singleRender();
		}
	}
}